package com.sw.fileServer.utils;


import io.minio.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

/**
 * @author xly
 * @date 2021-12-07 5:36 下午
 **/
@Slf4j
@Component
public class FileUploadUtil {

    /**
     * 文件服务器地址
     */
    @Value("${fileServer.hostPrefix}")
    private String hostPrefix;

    /**
     * 文件绝对路径前缀
     */
    @Value("${fileServer.absolutePathPrefix}")
    private String absolutePathPrefix;

    /**
     * 桶占位符
     */
    private static final String BUCKET_PARAM = "${bucket}";

    /**
     * bucket权限-读写
     */
    public static final String READ_WRITE = "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:GetBucketLocation\",\"s3:ListBucket\",\"s3:ListBucketMultipartUploads\"],\"Resource\":[\"arn:aws:s3:::" + BUCKET_PARAM + "\"]},{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:DeleteObject\",\"s3:GetObject\",\"s3:ListMultipartUploadParts\",\"s3:PutObject\",\"s3:AbortMultipartUpload\"],\"Resource\":[\"arn:aws:s3:::" + BUCKET_PARAM + "/*\"]}]}";

    /**
     * bucket权限-只写
     */
    public static final String WRITE_ONLY = "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:GetBucketLocation\",\"s3:ListBucketMultipartUploads\"],\"Resource\":[\"arn:aws:s3:::" + BUCKET_PARAM + "\"]},{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:AbortMultipartUpload\",\"s3:DeleteObject\",\"s3:ListMultipartUploadParts\",\"s3:PutObject\"],\"Resource\":[\"arn:aws:s3:::" + BUCKET_PARAM + "/*\"]}]}";

    /**
     * bucket权限-只读
     */
    public static final String READ_ONLY = "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:GetBucketLocation\",\"s3:ListBucket\"],\"Resource\":[\"arn:aws:s3:::" + BUCKET_PARAM + "\"]},{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:GetObject\"],\"Resource\":[\"arn:aws:s3:::" + BUCKET_PARAM + "/*\"]}]}";

    @Autowired
    private MinioClient minioClient;

    /**
     * 上传文件
     */
    public String uploadFile(MultipartFile file, String bucketName, String fileName) throws Exception {

        //判断文件桶是否存在
        boolean b = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
        if (!b) {
            minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
            //设置桶策略
            minioClient.setBucketPolicy(SetBucketPolicyArgs.builder().bucket(bucketName).config(READ_WRITE.replace(BUCKET_PARAM, bucketName)).build());
        }

        try (InputStream inputStream = file.getInputStream()) {
            minioClient.putObject(PutObjectArgs
                    .builder()
                    .bucket(bucketName)
                    .object(fileName)
                    //-1代表文件大于5M使用分片上传
                    .stream(inputStream, file.getSize(), -1)
                    .contentType(file.getContentType())
                    .build());
        }

        return hostPrefix + bucketName + File.separator + fileName;
    }

    /**
     * 转pdf
     */
//    public void toPdf(String bucketName, String fileName, String ext) throws Exception {
//
////        //转换命令
////        //unoconv -f pdf 文件绝对路径
////        String toPdfCmd = "unoconv -f pdf " + absolutePathPrefix + bucketName + File.separator + fileName;
////        log.info("toPdfCmd: {}", toPdfCmd);
////        Process toPdfProcess = Runtime.getRuntime().exec(toPdfCmd);
////        //等待命令执行完毕
////        toPdfProcess.waitFor();
////        toPdfProcess.destroy();
//        log.info("开始转换文件, bucketName: {}, fileName: {},   文件格式: {}", bucketName, fileName, ext);
//
//        switch (ext) {
//            case ".doc":
//                WordConvertPdfUtil.doc2pdf(absolutePathPrefix + bucketName + File.separator + fileName, absolutePathPrefix + bucketName + File.separator + fileName.replace(".doc", ".pdf"));
//                break;
//            case ".docx":
//                WordConvertPdfUtil.doc2pdf(absolutePathPrefix + bucketName + File.separator + fileName, absolutePathPrefix + bucketName + File.separator + fileName.replace(".docx", ".pdf"));
//                break;
//            case ".xls":
//                ExcelConvertPdfUtil.excel2pdf(absolutePathPrefix + bucketName + File.separator + fileName, absolutePathPrefix + bucketName + File.separator + fileName.replace(".xls", ".pdf"));
//                break;
//            case ".xlsx":
//                ExcelConvertPdfUtil.excel2pdf(absolutePathPrefix + bucketName + File.separator + fileName, absolutePathPrefix + bucketName + File.separator + fileName.replace(".xlsx", ".pdf"));
//                break;
//            case ".ppt":
//                PptConvertPdfUtil.ppt2Pdf(absolutePathPrefix + bucketName + File.separator + fileName, absolutePathPrefix + bucketName + File.separator + fileName.replace(".ppt", ".pdf"));
//                break;
//            case ".pptx":
//                PptConvertPdfUtil.ppt2Pdf(absolutePathPrefix + bucketName + File.separator + fileName, absolutePathPrefix + bucketName + File.separator + fileName.replace(".pptx", ".pdf"));
//                break;
//        }
//
//    }

    /**
     * 获取pdf信息
     */
    public int getPdfInfo(String bucketName, String fileName) throws Exception {

        //命令
        //pdfinfo 文件绝对路径
        String pdfInfoCmd = "pdfinfo " + absolutePathPrefix + bucketName + File.separator + fileName;
        log.info("pdfInfoCmd: {}", pdfInfoCmd);
        Process pdfinfoProcess = Runtime.getRuntime().exec(pdfInfoCmd);
        String line;
        int pages = 0;
        List<String> pdfinfo = new ArrayList<>();
        try (InputStream inputStream = pdfinfoProcess.getInputStream();
             InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
             BufferedReader bufferedReader = new BufferedReader(inputStreamReader)) {
            while ((line = bufferedReader.readLine()) != null) {
                line = line.replace(" ", "");
                pdfinfo.add(line);
                if (line.contains("Pages")) {
                    pages = Integer.parseInt(line.split(":")[1]);
                    break;
                }
            }
        }

        pdfinfoProcess.waitFor();
        pdfinfoProcess.destroy();

        log.info("pdfinfo: {}", pdfinfo);

        return pages;
    }
}
